package com.lc.offer;

/**
 * Java多线程看这一篇就足够了（吐血超详细总结） - Java团长 - 博客园
 * https://www.cnblogs.com/java1024/archive/2019/11/28/11950129.html
 * <p>
 * 继承 Thread 类
 */

class MyThread2 extends Thread {  // 继承Thread类，作为线程的实现类
	private String name;       // 表示线程S的名称

	public MyThread2(String name) {
		this.name = name;      // 通过构造方法配置name属性
	}

	public void run() {  // 覆写run()方法，作为线程 的操作主体
		for (int i = 0; i < 10; i++) {
			System.out.println(name + "运行，i = " + i);
		}
	}
}

// MyThread2 main
public class ThreadDemo02 {
	public static void main(String args[]) {
		MyThread2 mt1 = new MyThread2("线程A - 继承 Thread 类 ");    // 实例化对象
		MyThread2 mt2 = new MyThread2("线程B - 继承 Thread 类 ");    // 实例化对象
		mt1.start();   // 调用线程主体
		mt2.start();   // 调用线程主体
	}
}

/**
 * 从程序可以看出，现在的两个线程对象是交错运行的，哪个线程对象抢到了 CPU 资源，
 * 哪个线程就可以运行，所以程序每次的运行结果肯定是不一样的，
 * 在线程启动虽然调用的是 start() 方法，但实际上调用的却是 run() 方法定义的主体
 * <p>
 * 从定义中可以发现，在 Thread 类中的 run() 方法调用的是 Runnable 接口中的 run() 方法，也就是说此方法是由 Runnable 子类完成的，
 * 所以如果要通过继承 Thread 类实现多线程，则必须覆写 run()。
 * <p>
 * 实际上 Thread 类和 Runnable 接口之间在使用上也是有区别的，如果一个类继承 Thread类，
 * 则不适合于多个线程共享资源，而实现了 Runnable 接口，就可以方便的实现资源的共享。
 * <p>
 * 线程的状态变化
 * 要想实现多线程，必须在主线程中创建新的线程对象。任何线程一般具有5种状态，即创建，就绪，运行，阻塞，终止。下面分别介绍一下这几种状态：
 * <p>
 * 创建状态
 * <p>
 * 在程序中用构造方法创建了一个线程对象后，新的线程对象便处于新建状态，此时它已经有了相应的内存空间和其他资源，但还处于不可运行状态。
 * 新建一个线程对象可采用Thread 类的构造方法来实现，例如 “Thread thread=new Thread()”。
 * <p>
 * 就绪状态
 * <p>
 * 新建线程对象后，调用该线程的 start() 方法就可以启动线程。当线程启动时，线程进入就绪状态。此时，线程将进入线程队列排队，
 * 等待 CPU 服务，这表明它已经具备了运行条件。
 * <p>
 * 运行状态
 * <p>
 * 当就绪状态被调用并获得处理器资源时，线程就进入了运行状态。此时，自动调用该线程对象的 run() 方法。run() 方法定义该线程的操作和功能。
 * <p>
 * 阻塞状态
 * <p>
 * 一个正在执行的线程在某些特殊情况下，如被人为挂起或需要执行耗时的输入/输出操作，会让 CPU 暂时中止自己的执行，进入阻塞状态。
 * 在可执行状态下，如果调用sleep(),suspend(),wait() 等方法，线程都将进入阻塞状态，发生阻塞时线程不能进入排队队列，只有当引起阻塞的原因被消除后，
 * 线程才可以转入就绪状态。
 * <p>
 * 死亡状态
 * <p>
 * 线程调用 stop() 方法时或 run() 方法执行结束后，即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
 * <p>
 * 在此提出一个问题，Java 程序每次运行至少启动几个线程？
 * <p>
 * 回答：至少启动两个线程，每当使用 Java 命令执行一个类时，实际上都会启动一个 JVM，每一个JVM实际上就是在操作系统中启动一个线程，Java 本身具备了垃圾的收集机制。
 * 所以在 Java 运行时至少会启动两个线程，一个是 main 线程，另外一个是垃圾收集线程。
 * <p>
 * 线程的状态变化
 * 要想实现多线程，必须在主线程中创建新的线程对象。任何线程一般具有5种状态，即创建，就绪，运行，阻塞，终止。下面分别介绍一下这几种状态：
 * <p>
 * 创建状态
 * <p>
 * 在程序中用构造方法创建了一个线程对象后，新的线程对象便处于新建状态，此时它已经有了相应的内存空间和其他资源，但还处于不可运行状态。
 * 新建一个线程对象可采用Thread 类的构造方法来实现，例如 “Thread thread=new Thread()”。
 * <p>
 * 就绪状态
 * <p>
 * 新建线程对象后，调用该线程的 start() 方法就可以启动线程。当线程启动时，线程进入就绪状态。此时，线程将进入线程队列排队，
 * 等待 CPU 服务，这表明它已经具备了运行条件。
 * <p>
 * 运行状态
 * <p>
 * 当就绪状态被调用并获得处理器资源时，线程就进入了运行状态。此时，自动调用该线程对象的 run() 方法。run() 方法定义该线程的操作和功能。
 * <p>
 * 阻塞状态
 * <p>
 * 一个正在执行的线程在某些特殊情况下，如被人为挂起或需要执行耗时的输入/输出操作，会让 CPU 暂时中止自己的执行，进入阻塞状态。
 * 在可执行状态下，如果调用sleep(),suspend(),wait() 等方法，线程都将进入阻塞状态，发生阻塞时线程不能进入排队队列，只有当引起阻塞的原因被消除后，
 * 线程才可以转入就绪状态。
 * <p>
 * 死亡状态
 * <p>
 * 线程调用 stop() 方法时或 run() 方法执行结束后，即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
 * <p>
 * 在此提出一个问题，Java 程序每次运行至少启动几个线程？
 * <p>
 * 回答：至少启动两个线程，每当使用 Java 命令执行一个类时，实际上都会启动一个 JVM，每一个JVM实际上就是在操作系统中启动一个线程，Java 本身具备了垃圾的收集机制。
 * 所以在 Java 运行时至少会启动两个线程，一个是 main 线程，另外一个是垃圾收集线程。
 * <p>
 * 线程的状态变化
 * 要想实现多线程，必须在主线程中创建新的线程对象。任何线程一般具有5种状态，即创建，就绪，运行，阻塞，终止。下面分别介绍一下这几种状态：
 * <p>
 * 创建状态
 * <p>
 * 在程序中用构造方法创建了一个线程对象后，新的线程对象便处于新建状态，此时它已经有了相应的内存空间和其他资源，但还处于不可运行状态。
 * 新建一个线程对象可采用Thread 类的构造方法来实现，例如 “Thread thread=new Thread()”。
 * <p>
 * 就绪状态
 * <p>
 * 新建线程对象后，调用该线程的 start() 方法就可以启动线程。当线程启动时，线程进入就绪状态。此时，线程将进入线程队列排队，
 * 等待 CPU 服务，这表明它已经具备了运行条件。
 * <p>
 * 运行状态
 * <p>
 * 当就绪状态被调用并获得处理器资源时，线程就进入了运行状态。此时，自动调用该线程对象的 run() 方法。run() 方法定义该线程的操作和功能。
 * <p>
 * 阻塞状态
 * <p>
 * 一个正在执行的线程在某些特殊情况下，如被人为挂起或需要执行耗时的输入/输出操作，会让 CPU 暂时中止自己的执行，进入阻塞状态。
 * 在可执行状态下，如果调用sleep(),suspend(),wait() 等方法，线程都将进入阻塞状态，发生阻塞时线程不能进入排队队列，只有当引起阻塞的原因被消除后，
 * 线程才可以转入就绪状态。
 * <p>
 * 死亡状态
 * <p>
 * 线程调用 stop() 方法时或 run() 方法执行结束后，即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
 * <p>
 * 在此提出一个问题，Java 程序每次运行至少启动几个线程？
 * <p>
 * 回答：至少启动两个线程，每当使用 Java 命令执行一个类时，实际上都会启动一个 JVM，每一个JVM实际上就是在操作系统中启动一个线程，Java 本身具备了垃圾的收集机制。
 * 所以在 Java 运行时至少会启动两个线程，一个是 main 线程，另外一个是垃圾收集线程。
 * <p>
 * 线程的状态变化
 * 要想实现多线程，必须在主线程中创建新的线程对象。任何线程一般具有5种状态，即创建，就绪，运行，阻塞，终止。下面分别介绍一下这几种状态：
 * <p>
 * 创建状态
 * <p>
 * 在程序中用构造方法创建了一个线程对象后，新的线程对象便处于新建状态，此时它已经有了相应的内存空间和其他资源，但还处于不可运行状态。
 * 新建一个线程对象可采用Thread 类的构造方法来实现，例如 “Thread thread=new Thread()”。
 * <p>
 * 就绪状态
 * <p>
 * 新建线程对象后，调用该线程的 start() 方法就可以启动线程。当线程启动时，线程进入就绪状态。此时，线程将进入线程队列排队，
 * 等待 CPU 服务，这表明它已经具备了运行条件。
 * <p>
 * 运行状态
 * <p>
 * 当就绪状态被调用并获得处理器资源时，线程就进入了运行状态。此时，自动调用该线程对象的 run() 方法。run() 方法定义该线程的操作和功能。
 * <p>
 * 阻塞状态
 * <p>
 * 一个正在执行的线程在某些特殊情况下，如被人为挂起或需要执行耗时的输入/输出操作，会让 CPU 暂时中止自己的执行，进入阻塞状态。
 * 在可执行状态下，如果调用sleep(),suspend(),wait() 等方法，线程都将进入阻塞状态，发生阻塞时线程不能进入排队队列，只有当引起阻塞的原因被消除后，
 * 线程才可以转入就绪状态。
 * <p>
 * 死亡状态
 * <p>
 * 线程调用 stop() 方法时或 run() 方法执行结束后，即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
 * <p>
 * 在此提出一个问题，Java 程序每次运行至少启动几个线程？
 * <p>
 * 回答：至少启动两个线程，每当使用 Java 命令执行一个类时，实际上都会启动一个 JVM，每一个JVM实际上就是在操作系统中启动一个线程，Java 本身具备了垃圾的收集机制。
 * 所以在 Java 运行时至少会启动两个线程，一个是 main 线程，另外一个是垃圾收集线程。
 */

/**
 * 线程的状态变化
 * 要想实现多线程，必须在主线程中创建新的线程对象。任何线程一般具有5种状态，即创建，就绪，运行，阻塞，终止。下面分别介绍一下这几种状态：
 *
 * 创建状态
 *
 * 在程序中用构造方法创建了一个线程对象后，新的线程对象便处于新建状态，此时它已经有了相应的内存空间和其他资源，但还处于不可运行状态。
 * 新建一个线程对象可采用Thread 类的构造方法来实现，例如 “Thread thread=new Thread()”。
 *
 * 就绪状态
 *
 * 新建线程对象后，调用该线程的 start() 方法就可以启动线程。当线程启动时，线程进入就绪状态。此时，线程将进入线程队列排队，
 * 等待 CPU 服务，这表明它已经具备了运行条件。
 *
 * 运行状态
 *
 * 当就绪状态被调用并获得处理器资源时，线程就进入了运行状态。此时，自动调用该线程对象的 run() 方法。run() 方法定义该线程的操作和功能。
 *
 * 阻塞状态
 *
 * 一个正在执行的线程在某些特殊情况下，如被人为挂起或需要执行耗时的输入/输出操作，会让 CPU 暂时中止自己的执行，进入阻塞状态。
 * 在可执行状态下，如果调用sleep(),suspend(),wait() 等方法，线程都将进入阻塞状态，发生阻塞时线程不能进入排队队列，只有当引起阻塞的原因被消除后，
 * 线程才可以转入就绪状态。
 *
 * 死亡状态
 *
 * 线程调用 stop() 方法时或 run() 方法执行结束后，即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
 *
 * 在此提出一个问题，Java 程序每次运行至少启动几个线程？
 *
 * 回答：至少启动两个线程，每当使用 Java 命令执行一个类时，实际上都会启动一个 JVM，每一个JVM实际上就是在操作系统中启动一个线程，Java 本身具备了垃圾的收集机制。
 * 所以在 Java 运行时至少会启动两个线程，一个是 main 线程，另外一个是垃圾收集线程。
 */

// 其他 请看上面博客

